#include "bsp_ioi2c.h"
#include "bsp.h"
#include "driver/ioi2c.h"
#include "stm32f1xx_ll_gpio.h"

//
//
// PB4 SCL
// PB3 SDA

// PB11 SDA
// PB10 SCL

ioi2c_t g_i2c_1;

#define IOI2C_1_SDA_PIN   (LL_GPIO_PIN_3)
#define IOI2C_1_SCL_PIN   (LL_GPIO_PIN_4)

void bsp_ioi2c_io_init() {
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  GPIO_InitStruct.Pin = IOI2C_1_SCL_PIN|IOI2C_1_SDA_PIN;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_MODE_OUTPUT_50MHz;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  // default level
  LL_GPIO_SetOutputPin(GPIOB, IOI2C_1_SCL_PIN|IOI2C_1_SDA_PIN);
}

static void bsp_i2c_set_scl(bool level) {
  level ? LL_GPIO_SetOutputPin(GPIOB, IOI2C_1_SCL_PIN) : LL_GPIO_ResetOutputPin(GPIOB, IOI2C_1_SCL_PIN);
}

static void bsp_i2c_set_sda(bool level) {
  level ? LL_GPIO_SetOutputPin(GPIOB, IOI2C_1_SDA_PIN) : LL_GPIO_ResetOutputPin(GPIOB, IOI2C_1_SDA_PIN);
}

static bool bsp_i2c_get_scl(void) { return (LL_GPIO_ReadInputPort(GPIOB) & IOI2C_1_SCL_PIN) != 0; }

static bool bsp_i2c_get_sda(void) { 
LL_GPIO_ReadInputPort(GPIOB);
return (LL_GPIO_ReadInputPort(GPIOB) & IOI2C_1_SDA_PIN) == IOI2C_1_SDA_PIN;
 }

static void bsp_i2c_delay(void) {
  bsp_delay_us(5);  // 100K
}

int bsp_ioi2c_init() {
  bsp_ioi2c_io_init();

  g_i2c_1.delay = bsp_i2c_delay;
  g_i2c_1.sda_dir = NULL;
  g_i2c_1.set_scl = bsp_i2c_set_scl;
  g_i2c_1.set_sda = bsp_i2c_set_sda;
  g_i2c_1.get_scl = bsp_i2c_get_scl;
  g_i2c_1.get_sda = bsp_i2c_get_sda;

  return 0;
}